﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using LingDong.CommonUtility;
using System.Runtime.Serialization.Formatters.Binary;

namespace LingDong.HtmlClassification
{
	public class BayesLearn
	{
        public BayesLearn()
        {
        }

        public void Learn()
        {
            P_f_c = new double[BayesUtility.FeatureNumber, BayesUtility.CategoryNumber, BayesUtility.Dimensionality];
            p_f_c_num = new int[BayesUtility.FeatureNumber, BayesUtility.CategoryNumber, BayesUtility.Dimensionality];

            int[] docNumber = new int[BayesUtility.CategoryNumber];
            for (int i = 0; i < BayesUtility.CategoryNumber; i++)
            {
                string dir = BayesSettings.Default.LearnBasePath + BayesSettings.Default.CategoryPath[i];
                string[] fileList = Directory.GetFiles(dir);
                docNumber[i] = fileList.Count();

                foreach (string file in fileList)
                {
                    LearnOneFile(i, file);
                }
            }

            for (int i = 0; i < BayesUtility.FeatureNumber; i++)
                for (int j = 0; j < BayesUtility.CategoryNumber; j++)
                {
                    int zeroNum = Smooth_P_F_C(i, j);
                    for (int k = 0; k < BayesUtility.Dimensionality; k++)
                        P_f_c[i, j, k] = (double)p_f_c_num[i, j, k] / (docNumber[j] + zeroNum);
                }
        }

        public void SaveResult()
        {
            BinaryFormatter formatter = new BinaryFormatter();
            using (FileStream fs = new FileStream(BayesSettings.Default.LearnResultFile, FileMode.Create))
            {
                formatter.Serialize(fs, P_f_c);
            }
        }

        internal void ReadResult()
        {
            BinaryFormatter formatter = new BinaryFormatter();
            using (FileStream fs = new FileStream(BayesSettings.Default.LearnResultFile, FileMode.Open))
            {
                P_f_c = (double[, ,])formatter.Deserialize(fs);
            }
        }

        private void LearnOneFile(int category, string file)
        {
            string html = Utility.GetFileContent(file);
            int[] featureList = BayesUtility.GetHtmlFeature(html);
            for (int i = 0; i < BayesUtility.FeatureNumber; i++)
            {
                p_f_c_num[i, category, featureList[i]]++;
            }
        }

        private int Smooth_P_F_C(int i, int j)
        {
            int zeroNum = 0;
            for (int k = 0; k < BayesUtility.Dimensionality; k++)
                if (p_f_c_num[i, j, k] == 0)
                {
                    p_f_c_num[i, j, k] = 1;
                    zeroNum++;
                }
            return zeroNum;
        }

        private int[, ,] p_f_c_num;

        //[Serializable]
        public double[, ,] P_f_c { get; private set; }

    }
}
